// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: chunhui

#pragma once

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <fmt/format.h>
#include <glog/logging.h>

#include "cc/appcoin2/support/feed/interval_feed_tool/feed_summary_calculator.h"
#include "cc/appcoin2/support/feed/interval_feed_tool/h5_dumper.h"
#include "cc/appcoin2/support/feed/interval_feed_tool/util.h"
#include "coin2/exchange/base/order/order.h"
#include "coin2/exchange/base/symbology/product.h"
#include "coin2/exchange/base/symbology/product_encyclopedia.h"
#include "coin2/exchange/feed.pb.h"
#include "coin2/exchange/interval_feed_enum.pb.h"

namespace interval_feed {

using coin2::exchange::base::feed::FeedUpdate;
using coin2::exchange::base::symbology::IProduct;
using coin2::exchange::base::symbology::ProductEncyclopedia;

class IntervalFeedConsumer {
 public:
  // start_ts should be in nanoseconds, resolution should be in seconds
  IntervalFeedConsumer(int64_t start_ts, int resolution, int n_intervals)
      : start_ts_(start_ts), resolution_(resolution), n_intervals_(n_intervals) {
    InitTimestamp(resolution);
    product_cache_ = std::make_unique<ProductEncyclopedia>();
  }

  void Write(const std::string& file_prefix, const WriterOptions& option);
  void Consume(const FeedUpdate& upd, FeedType feed_type);

 private:
  int64_t start_ts_;
  int resolution_;
  int n_intervals_;
  std::vector<std::string> all_symbols_;
  std::vector<int64_t> all_ts_;
  std::map<std::string, int> symbol_id_;
  std::map<int, int> previous_interval_id_;
  std::vector<std::unique_ptr<IProduct>> all_products_;
  std::vector<std::vector<FeedSummaryCalculator>> symbol_to_calculators_;
  std::unique_ptr<ProductEncyclopedia> product_cache_;

  int64_t GetIntervalId(int64_t ts) const;
  void InitTimestamp(int resolution);
  void WriteOhlc(const std::string& file_prefix);
  void WriteVwap(const std::string& file_prefix);
  void WriteVolume(const std::string& file_prefix);
  void WriteOtherStats(const std::string& file_prefix);
  void WriteTime(const std::string& file_prefix);
  void WriteMarketAnalysis(const std::string& file_prefix);

  void PopulateData(
      const std::string& data_frame,
      OhlcType ohlc_type,
      PriceType price_type,
      VwapType vwap_type,
      VolumeType volume_type,
      QuoteType quote_type,
      OtherStatsType other_stats_type,
      TsType ts_type,
      MarketAnalysisType ma_type,
      LongShortRatioType lsr_type,
      std::vector<double>* data);
};

}  // namespace interval_feed
